1 /************************************************************
2 * Copyright *
3 * Portions of this software are Copyright (c) 1993 - 2002, *
4 * Chad Z. Hower (Kudzu) and the Indy Pit Crew *
5 * - http://www.nevrona.com/Indy/ *
6 ************************************************************/
7 package org.indy;
8
9 import java.util.Collection;
10 import java.util.HashSet;
11 import java.util.Iterator;
12 import java.util.StringTokenizer;
13
14 import org.indy.util.StringList;
15
16
17 /***
18 * Provides the basis for {@link TCPServer} command handling.
19 *
20 *@version 1.0
21 *@author OTG
22 */
23 public class CommandHandler {
24 private char cmdDelimiter;
25 private boolean disconnect;
26 private boolean enabled;
27 private String command;
28 private char paramDelimiter;
29 private boolean parseParams;
30 private int replyExceptionCode;
31 private RFCReply replyNormal;
32 private StringList response = new StringList();
33 private int tag;
34 private final CommandHandlers handlersList;
35 private Collection commandListeners = new HashSet();
36
37 /***
38 * Constructs a new instance. Takes a
39 * reference to this handler's containing {@link CommandHandlers}
40 * collection.
41 *
42 * @param collection The <code>CommandHandlers</code> collection that contains this handler.
43 */
44 public CommandHandler(CommandHandlers collection) {
45 handlersList = collection;
46 }
47
48 /***
49 * Sets the command delimiter for this handler object.
50 *
51 *@param cmdDelimiter The new delimiter value
52 */
53 public void setCmdDelimiter(char cmdDelimiter) {
54 this.cmdDelimiter = cmdDelimiter;
55 }
56
57 /***
58 * Sets whether this handler should disconnect from the client when it has finished.
59 *
60 *@param disconnect The new disconnect value
61 */
62 public void setDisconnect(boolean disconnect) {
63 this.disconnect = disconnect;
64 }
65
66 /***
67 * Enables / disables this handler.
68 *
69 *@param enabled <code>true</code> to enable the handler, <code>false</code> to disable.
70 */
71 public void setEnabled(boolean enabled) {
72 this.enabled = enabled;
73 }
74
75 /***
76 * Sets command string that this handler is associated with.
77 *
78 *@param command The new command value
79 */
80 public void setCommand(String command) {
81 this.command = command;
82 }
83
84 /***
85 * Sets the parameter delimiter for this handler.
86 *
87 *@param paramDelimiter The new parameter delimiter.
88 */
89 public void setParamDelimiter(char paramDelimiter) {
90 this.paramDelimiter = paramDelimiter;
91 }
92
93 /***
94 * Sets whether this handler should attempt to parse the parameters sent to it.
95 *
96 *@param parseParams <code>true</code> to enable parsing, <code>false</code> to disable.
97 */
98 public void setParseParams(boolean parseParams) {
99 this.parseParams = parseParams;
100 }
101
102 /***
103 * Sets the numerical code for this handler to use if an exception is encountered during processing (e.g. 500 for an http server).
104 *
105 *@param replyExceptionCode The numerical reply for exception conditions
106 */
107 public void setReplyExceptionCode(int replyExceptionCode) {
108 this.replyExceptionCode = replyExceptionCode;
109 }
110
111 /***
112 * Sets the standard {@link org.indy.RFCReply} object to use as a response to this command
113 *
114 *@param replyNormal The new replyNormal value
115 */
116 public void setReplyNormal(RFCReply replyNormal) {
117 this.replyNormal = replyNormal;
118 }
119
120 /***
121 * Sets the {@link org.indy.util.StringList} that form the textual reponse for this command handler.
122 *
123 *@param response The new response value
124 */
125 public void setResponse(StringList response) {
126 /***
127 *@todo Use copy constructor?
128 */
129 this.response.copy(response);
130 }
131
132 /***
133 * Sets the tag attribute of the <code>CommandHandler</code> object
134 *
135 *@param tag The new tag value
136 */
137 public void setTag(int tag) {
138 this.tag = tag;
139 }
140
141 /***
142 * Returns the containing collection of this command handler.
143 *
144 *@return The commandHandlers value
145 */
146 public CommandHandlers getCommandHandlers() {
147 return handlersList;
148 }
149
150 /***
151 * Gets the command delimiter for this command handler
152 *
153 *@return The cmdDelimiter value
154 */
155 public char getCmdDelimiter() {
156 return cmdDelimiter;
157 }
158
159 /***
160 * Gets the disconnect attribute of the <code>CommandHandler</code> object
161 *
162 *@return The disconnect value
163 */
164 public boolean isDisconnected() {
165 return disconnect;
166 }
167
168 /***
169 * Gets the enabled attribute of the IdCommandHandler object
170 *
171 *@return The enabled value
172 */
173 public boolean isEnabled() {
174 return enabled;
175 }
176
177 /***
178 * Gets the command attribute of the IdCommandHandler object
179 *
180 *@return The command value
181 */
182 public String getCommand() {
183 return command;
184 }
185
186 /***
187 * Gets the paramDelimiter attribute of the IdCommandHandler object
188 *
189 *@return The paramDelimiter value
190 */
191 public char getParamDelimiter() {
192 return paramDelimiter;
193 }
194
195 /***
196 * Gets the parseParams attribute of the <code>CommandHandler</code> object
197 *
198 *@return The parseParams value
199 */
200 public boolean isParseParams() {
201 return parseParams;
202 }
203
204 /***
205 * Gets the replyExceptionCode attribute of the <code>CommandHandler</code> object
206 *
207 *@return The replyExceptionCode value
208 */
209 public int getReplyExceptionCode() {
210 return replyExceptionCode;
211 }
212
213 /***
214 * Gets the replyNormal attribute of the <code>CommandHandler</code> object
215 *
216 *@return The replyNormal value
217 */
218 public RFCReply getReplyNormal() {
219 return replyNormal;
220 }
221
222 /***
223 * Gets the response attribute of the CommandHandler object
224 *
225 *@return The response value
226 */
227 public StringList getResponse() {
228 return response;
229 }
230
231 /***
232 * Gets the tag attribute of the CommandHandler object
233 *
234 *@return The tag value
235 */
236 public int getTag() {
237 return tag;
238 }
239
240 /***
241 * Calls all {@link CommandListener}'s {@link CommandListener#onCommand()} method.
242 *
243 *@param command The {@link IdCommand} object to pass.
244 *@throws IdException If an exception is thrown by the IdCommandListener
245 */
246 protected void doCommand(CommandEvent command) throws IndyException {
247 synchronized (commandListeners) {
248 Iterator i = commandListeners.iterator();
249
250 while (i.hasNext()) {
251 ((CommandHandlerListener) i.next()).onCommand(command);
252 }
253 }
254 }
255
256 /***
257 * Parses a command, notifies any {@link IdCommandListener} instances
258 * that are registered, and returns <code>true</code> if the
259 * command was recognised.
260 *
261 *@param data The command to parse.
262 *@param thread The thread that received the command.
263 *@return <code>true</code> if the command was recognized and parsed sucessfully, <code>false</code> otherwise.
264 *@throws IdException If an exeception is encountered whilst processing the command.
265 */
266 final boolean check(String data, PeerThread thread) throws IndyException {
267 boolean result = command.equalsIgnoreCase(data);
268 String unparsedParams = null;
269
270 if (!result && (data.length() > command.length())) {
271 if (cmdDelimiter != '\u0000') {
272 result = data.substring(0, command.length())
273 .equalsIgnoreCase(command + cmdDelimiter);
274 unparsedParams = data.substring(command.length() + 1);
275 }
276 else {
277 result = data.substring(0, command.length() - 1)
278 .equalsIgnoreCase(command);
279 unparsedParams = data.substring(command.length());
280 }
281 }
282
283 if (result) {
284 CommandEvent command = new CommandEvent();
285
286 try {
287 command.setCommandHandler(this);
288 command.setRawLine(data);
289 command.setThread(thread);
290 command.setUnparsedParams(unparsedParams);
291 command.setPerformReply(true);
292 command.setReply(this.replyNormal);
293
294 if (parseParams) {
295 StringTokenizer tok = new StringTokenizer(data,
296 String.valueOf(
297 paramDelimiter));
298 StringList params = command.getParams();
299
300 while (tok.hasMoreTokens()) {
301 params.add(tok.nextToken());
302 }
303
304
305 //end while
306 command.setUnparsedParams("");
307 }
308 else {
309 command.getParams().add(unparsedParams);
310 }
311
312 //if parse params
313 while (true) {
314 try {
315 doCommand(command);
316 }
317 catch (IndyException ide) {
318 if (command.getPerformReply()) {
319 if (replyExceptionCode > 0) {
320 command.getReply()
321 .setReply(replyExceptionCode, ide.getMessage());
322 command.sendReply();
323 }
324 else {
325 throw ide;
326 }
327
328 //if reply exception code > 0
329 break;
330 }
331
332 //if command.performReply
333 else {
334 throw ide;
335 }
336
337 //!command.performReply
338 }
339
340 //catch
341 if (command.getPerformReply()) {
342 command.sendReply();
343 }
344
345 if (command.getResponse().size() > 0) {
346 thread.getConnection().writeRFCStrings(command.getResponse());
347 }
348 else if (this.response.size() > 0) {
349 thread.getConnection().writeRFCStrings(this.response);
350 }
351
352 break;
353 }
354
355 //while
356 }
357 finally {
358 if (disconnect) {
359 command = null;
360 thread.getConnection().disconnect();
361 }
362 }
363 }
364
365 //if
366 return result;
367 }
368
369 /***
370 * Unregisters an {@link IdCommandListener} instance.
371 *
372 *@param l The listener to remove.
373 */
374 public synchronized void removeCommandListener(CommandHandlerListener l) {
375 commandListeners.remove(l);
376 }
377
378 /***
379 * Registers an {@link IdCommandListener} instance to be informed of
380 * events from this handler.
381 *
382 *@param l The listener to add.
383 */
384 public synchronized void addCommandListener(CommandHandlerListener l) {
385 commandListeners.add(l);
386 }
387 }
This page was automatically generated by Maven